/*
   Copyright (c) 2023 李伟国
   learner-platform is licensed under Mulan PSL v2.
   You can use this software according to the terms and conditions of the Mulan PSL v2.
   You may obtain a copy of Mulan PSL v2 at:
            http://license.coscl.org.cn/MulanPSL2
   THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
   See the Mulan PSL v2 for more details.
*/

package cn.platform.entity;


import cn.platform.config.JudgeSourceProperties;
import cn.platform.constant.ProblemConstant;
import cn.platform.dto.CodeRunMsg;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;

@Component
public class Runner implements ProblemConstant {

    private static String onlineJudgePath;
    private static String languageConfigPath;
    private static String problemRootPath;
    @Autowired
    private JudgeSourceProperties judgeSourceProperties(JudgeSourceProperties judgeSourcePropertiess) {
        onlineJudgePath = judgeSourcePropertiess.getOnlineJudgePath();
        languageConfigPath = judgeSourcePropertiess.getLanguageConfigPath();
        problemRootPath = judgeSourcePropertiess.getProblemRootPath();
        return judgeSourcePropertiess;
    }


    private Integer problemId;  // 题目id
    /**
     * 测试类型(用于选择使用哪个测试文件夹)
     */
    private String testType;
    /**
     * 源代码
     */
    private String code;
    private String filePrefix;  // 文件前缀名
    private String fileSuffix;  // 文件后缀名
    private String language;  // 语言
    private String languageDir;  // 语言文件夹
    private String filePath;  // 测试源代码文件路径
    private Integer time;  // 限时
    private Integer memory;  // 内存
    private String mode;  // 测试模式
    /**
     * 接受结果的类型
     */
    private String type;
    private Boolean deleteFile;  // 删除测试源代码
    private String judgePath;  // judge执行路径
    private String testDir;  // 测试文件夹
    private String codeResultDir;  // 代码结果的生成路径

    public Runner() {
        mode = "entire";
        type = "json";
        deleteFile = false;
        languageDir = languageConfigPath;
        memory = 2000000;
        time = 1000;
        judgePath = onlineJudgePath;
        filePath = problemRootPath+File.separator+"CODE";
        codeResultDir = filePath;
    }

    public String getCode() {
        return code;
    }

    public Runner setCode(String code) {
        this.code = code;
        return this;
    }

    public Integer getProblemId() {
        return problemId;
    }

    public String getTestType(){
        return testType;
    }

    public Runner setProblemIdAndTestType(Integer problemId, String testType) {
        this.problemId = problemId;
        this.testType = testType;
        this.testDir = problemRootPath+ File.separator+problemId+File.separator+testType;
        return this;
    }

    public String getFilePrefix() {
        return filePrefix;
    }

    public Runner setFilePrefix(String filePrefix) {
        this.filePrefix = filePrefix;
        return this;
    }

    public String getFileSuffix() {
        return fileSuffix;
    }

    public Runner setFileSuffix(String fileSuffix) {
        this.fileSuffix = fileSuffix;
        return this;
    }

    public String getLanguage() {
        return language;
    }

    public Runner setLanguage(String language) {
        this.language = language;
        return this;
    }

    public String getLanguageDir() {
        return languageDir;
    }

    public Runner setLanguageDir(String languageDir) {
        this.languageDir = languageDir;
        return this;
    }

    public String getFilePath() {
        return filePath;
    }

    public Runner setFilePath(String filePath) {
        this.filePath = filePath;
        return this;
    }

    public Runner setFilePath(Integer problemId, String filePath) {
        this.filePath = problemRootPath+ File.separator+problemId+File.separator+filePath;
        return this;
    }

    public Integer getTime() {
        return time;
    }

    public Runner setTime(Integer time) {
        this.time = time;
        return this;
    }

    public Integer getMemory() {
        return memory;
    }

    public Runner setMemory(Integer memory) {
        this.memory = memory;
        return this;
    }

    public String getMode() {
        return mode;
    }

    public Runner setMode(String mode) {
        this.mode = mode;
        return this;
    }

    public String getType() {
        return type;
    }

    public Runner setType(String type) {
        this.type = type;
        return this;
    }

    public Boolean getDeleteFile() {
        return deleteFile;
    }

    public Runner setDeleteFile(Boolean deleteFile) {
        this.deleteFile = deleteFile;
        return this;
    }

    public String getJudgePath() {
        return judgePath;
    }

    public Runner setJudgePath(String judgePath) {
        this.judgePath = judgePath;
        return this;
    }

    public String getTestDir() {
        return testDir;
    }

    public Runner setTestDir(String testDir) {
        this.testDir = testDir;
        return this;
    }

    public String getCodeResultDir() {
        return codeResultDir;
    }

    public Runner setCodeResultDir(String codeResultDir) {
        this.codeResultDir = codeResultDir;
        return this;
    }

    public Runner setCodeResultDir(Integer problemId, String codeResultDir) {
        this.codeResultDir = problemRootPath+File.separator+problemId+File.separator+codeResultDir;
        return this;
    }

    public Runner setRunMsg(CodeRunMsg codeRunMsg){
        this.setFilePrefix(codeRunMsg.getFilePrefix());
        this.setLanguage(codeRunMsg.getLang());
        this.setFileSuffix(codeRunMsg.getFileSuffix());
        if(codeRunMsg.getProblemId()!=null){
            this.setProblemIdAndTestType(codeRunMsg.getProblemId(),null);
        }
        return this;
    }

    public CodeRunMsg getCodeRunMsg(){
        CodeRunMsg codeRunMsg = new CodeRunMsg();
        codeRunMsg.setCode(this.code);
        codeRunMsg.setLang(this.language);
        codeRunMsg.setFileSuffix(this.fileSuffix);
        codeRunMsg.setFilePrefix(this.filePrefix);
        codeRunMsg.setProblemId(this.problemId);
        return codeRunMsg;
    }

    /**
     * 得到执行命令
     * @return 执行命令
     */
    public String getRunCmd(){
        return  "python3 " + judgePath +
                " --language " + language +
                " --languageConfig " + languageDir +
                " --file " + filePrefix+fileSuffix +
                " --filePath " + filePath +
                " --time " + time +
                " --memory " + memory +
                " --mode " + mode +
                " --type " + type +
                " --deleteFile " + deleteFile +
                " --testDir " + testDir +
                " --codeResultDir " + codeResultDir;
    }

    @Override
    public String toString() {
        return "Runner{" +
                "filePrefix='" + filePrefix + '\'' +
                ", fileSuffix='" + fileSuffix + '\'' +
                ", language='" + language + '\'' +
                ", languageDir='" + languageDir + '\'' +
                ", filePath='" + filePath + '\'' +
                ", time=" + time +
                ", memory=" + memory +
                ", mode='" + mode + '\'' +
                ", type='" + type + '\'' +
                ", deleteFile=" + deleteFile +
                ", judgePath='" + judgePath + '\'' +
                ", testDir='" + testDir + '\'' +
                ", codeResultDir='" + codeResultDir + '\'' +
                '}';
    }
}
